/*
 * Alan Fortes
 * 3/28/15, cpe301
 * Design assignment 3
 *
 * The following C code displays the current
 * temperature every second through the use
 * of an LM 34 temperature sensor, which employs
 * analog to digital conversion, as well as an
 * interrupt to display the information every
 * second.
 */

// All of the necessary header files
// are included to receive and transmit
// information, as well as activate
// interrupts.
#include <avr/io.h>
#include <stdio.h>
#include <avr/interrupt.h>

void printStringToScreen(char *sentence)
{
    while ((*sentence !='\0')){ // While the end of the sentence hasn't been reached
                                // the output string will be displayed, character by character.
                                 
        while(!(UCSR0A&(1<<UDRE0)));
               
        UDR0 = *sentence;
   
        sentence++; // The position of next character of the output string is gotten.
    }
   
}

int main(void)
{
    DDRD = 0xFF; //The D port is set to be output, so that the ATMega328p
                 //is capable of transmitting data serially from the TXD/PD1
                 //to the serial to usb converter's RX port.
   
    DDRC = 0;      // The C port is set to be input so that the LM34 can send in an analog signal to PC/ADC0.
   
    ADCSRA = 0x82; // The ADEN bit, bit 7, of ADCSRA register is activated by setting the upper 4 bits to be a value of 8.
   
    ADMUX = 0x00;  // Admux is set to be 0 zero so that ref1 and ref0 use Vref, and that ADC0 will act as input.
   
    UCSR0B = 0x08;  // TXEN0, bit 3, decimal value 8, is set high to enable the ATMega328p to transmit information, serially.
    UCSR0C = 0x06;  // UCSZ01 and UCSZ00, decimal values 4 and 2, are set high so that
    UBRR0 = 0x0033; // With a baud rate of 9600, the value of UBRR0 will be, 8000000/(16*9600) - 1 = 51.083 = 51 = 0x33.
    TCCR1A = 0x00;  // TCCR1A is set to have a value of 0 so that regular clock is used.

    TCCR1B = 0x0D; // The TCCR1B register is given a value of D, indicating that bit 3, WSM12,
                   // decimal value 8, has been set high, meaning that CTC mode has been enabled.
                   // Bits 0 and 2, CsN0 and CsN2, have also been set high, a decimal value of 5,
                   // meaning that CTC mode is using a prescaler of 1024.
   
    OCR1A = 0x1E84; // In order for an interrupt to occur ever second, using a prescaler of 1024,
                    // the value of OCR1A must be (8000000 * 1)/1024 = 7812.5, 7812 = 0x1E84.
   
    TIMSK1 |= (1 << OCIE1A); // The OCIE1A bit of the TIMSK1 register is set so
                             // when TCNT1A reaches the value of OCR1A, the
                             // interrupt function at the bottom is called.
   
    sei(); // The interrupt enable is set to allow for interrupts to occur.
   
    while(1){ // This loop will cause the program to run indefinitely, only leaving
    }         // this loop to go to the interrupt function every second.
}

// After 1 second has passed, the interrupt
// function is activated. 
ISR(TIMER1_COMPA_vect){
   
    char outputString[999]; // This string variable will hold the sentence that
                            // displayed to the screen.
   
    int temperature; // This integer variable will hold the result of
                     // the ADC conversion that represents the temperature.
   
    ADCSRA |= (1<<ADSC);
    while((ADCSRA&(1<<ADIF))==0);
                           
    static int secondsPassed; // This integer variable will store the amount of
                              // seconds that have elapsed since the beginning
                              // of the programming of the ATMega328p.
                             
    temperature = ADC; // The temperature result of the analog to digital
                       // conversion is stored in the variable temperature,
                       // which is displayed along with the output string.
   
    secondsPassed++;   // Since this interrupt function is activated
                       // every second, this variable is incremented,
                       // so that it may reflect the time elapsed. 
   
   
    snprintf(outputString,sizeof(outputString), "The current temperature is: %3d\n\rSeconds passed have been:  %3d\r\n\n", temperature, secondsPassed);
    printStringToScreen(outputString);
   
   
}